package me.fung.wubi.app.view.editor

import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowForward
import androidx.compose.material.icons.filled.ExitToApp
import androidx.compose.material.icons.filled.Search
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import me.fung.keen.app.view.View
import me.fung.wubi.app.component.*
import me.fung.wubi.app.navigation
import me.fung.wubi.app.view.editor.item.CodeItemComp
import me.fung.wubi.base.define.value.toCode
import me.fung.wubi.base.define.value.toWord

const val EDITOR_VIEW = "editor_view"

class EditorView(
    private val filename: String
) : View<EditorPresenter>() {
    @Composable
    override fun content(modifier: Modifier) {
        LaunchedEffect(filename) {
            p.updateTable(filename, null, null)
        }
        Column(modifier = modifier.padding(3.dp)) {
            title(modifier = Modifier.padding(horizontal = 50.dp))
            body(modifier = Modifier.weight(1f).fillMaxWidth())
            bottom(modifier = Modifier.height(ButtonDefaults.MinHeight))
        }
    }

    @Composable
    private fun title(modifier: Modifier) {
        Row(
            modifier = modifier,
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.End
        ) {
            Spacer(Modifier.weight(1f))
            Text("编辑资源文件：${filename}")
            Spacer(Modifier.weight(1f))
        }
    }

    @Composable
    private fun body(modifier: Modifier) {
        Row(modifier = modifier) {
            contentAreal(Modifier.weight(1f).fillMaxHeight().border(1.dp, Color.LightGray))
            Spacer(Modifier.size(5.dp))
            toolPanel(Modifier.width(280.dp).padding(top = 5.dp).fillMaxHeight())
        }
    }

    // 底部导航按钮
    @Composable
    private fun bottom(modifier: Modifier) {
        Row(
            modifier = modifier
        ) {
            Spacer(Modifier.width(10.dp).weight(1f))
            imageVectorButton(
                tooltip = "返回",
                icon = Icons.Default.ExitToApp,
                onClick = {
                    navigation.goBack()
                },
                modifier = Modifier.fillMaxHeight(),
            )
        }
    }
}


@Composable
private fun EditorView.toolPanel(modifier: Modifier) {
    Column(
        modifier,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        searchFilter(modifier = Modifier.fillMaxWidth())
        codeLengthFilter(modifier = Modifier.fillMaxWidth())
        wordRepeatSizeFilter(modifier = Modifier.fillMaxWidth())
        wordLengthFilter(modifier = Modifier.fillMaxWidth())
        wordFreqFilter(modifier = Modifier.fillMaxWidth())
        lexiconFilter(modifier = Modifier.fillMaxWidth())
        editorButtons(modifier = Modifier.fillMaxWidth())
        Spacer(Modifier.weight(1f))
        outputAreal(modifier = Modifier.fillMaxWidth())
    }
}

@Composable
private fun EditorView.outputAreal(modifier: Modifier) {
    Column(modifier) {
        Row {
            checkBox(
                text = "不输出编码", checked = p.model.data.outNoCode,
                onCheckedChange = {
                    p.model.update { copy(outNoCode = !outNoCode) }
                },
                modifier = Modifier.weight(1f)
            )
        }
        Button(onClick = { p.out() }, modifier = Modifier.fillMaxWidth()) { Text("提取当前结果码表") }
    }
}

@Composable
private fun EditorView.editorButtons(modifier: Modifier) {
    Row(modifier) {
        p.model.data.wordFrequency?.also { wf ->
            Button(onClick = {
                p.model.data.table.forEach {
                    it.value.sortByFreq(wf)
                }
                p.update()
                p.save()
            }) {
                Text("按照词频自动排序")
            }
        }
    }

}

@Composable
private fun EditorView.lexiconFilter(modifier: Modifier) {
    Row(modifier) {
        p.model.data.lexicon?.also { _ ->
            checkBox(
                text = "仅简码",
                checked = p.filterState.value.onlyShort,
                onCheckedChange = { p.updateFilter { copy(onlyShort = it) } }
            )
        }
    }
}

@Composable
private fun EditorView.searchFilter(modifier: Modifier) {
    val filter by p.filterState
    Column(modifier) {
        Text("搜索")
        SearchButton(
            value = filter.value,
            onValueChange = {
                p.updateFilter { copy(value = it) }
            },
            modifier = Modifier.border(1.dp, Color.LightGray, RoundedCornerShape(50)).padding(3.dp).fillMaxWidth(),
            widthIn = 200.dp to 300.dp,
            enabled = false,
        ) {
            Icon(Icons.Default.Search, "")
        }
    }
}

@Composable
private fun EditorView.codeLengthFilter(modifier: Modifier) {
    val filter by p.filterState
    groupColumn("编码长度", modifier = modifier) {
        Row {
            checkBox(
                text = "一码", checked = filter.cl1,
                onCheckedChange = { p.updateFilter { copy(cl1 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )
            checkBox(
                text = "二码", checked = filter.cl2,
                onCheckedChange = { p.updateFilter { copy(cl2 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )
        }
        Row {
            checkBox(
                text = "三码", checked = filter.cl3,
                onCheckedChange = { p.updateFilter { copy(cl3 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )
            checkBox(
                text = "四码", checked = filter.cl4,
                onCheckedChange = { p.updateFilter { copy(cl4 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )
        }
    }
}

@Composable
private fun EditorView.wordRepeatSizeFilter(modifier: Modifier) {
    val filter by p.filterState
    groupColumn("重码数", modifier = modifier) {
        Row {
            checkBox(
                text = "一重", checked = filter.w1,
                onCheckedChange = { p.updateFilter { copy(w1 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )
            checkBox(
                text = "二重", checked = filter.w2,
                onCheckedChange = { p.updateFilter { copy(w2 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )
        }
        Row {
            checkBox(
                text = "三重", checked = filter.w3,
                onCheckedChange = { p.updateFilter { copy(w3 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )
            checkBox(
                text = "多重", checked = filter.w9,
                onCheckedChange = { p.updateFilter { copy(w9 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )
        }
    }
}

@Composable
private fun EditorView.wordLengthFilter(modifier: Modifier) {
    val filter by p.filterState
    groupColumn("词条长度", modifier = modifier) {
        Row {
            checkBox(
                text = "一字", checked = filter.l1,
                onCheckedChange = { p.updateFilter { copy(l1 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )
            checkBox(
                text = "二字", checked = filter.l2,
                onCheckedChange = { p.updateFilter { copy(l2 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )

            checkBox(
                text = "三字", checked = filter.l3,
                onCheckedChange = { p.updateFilter { copy(l3 = it) } },
                modifier = Modifier.width(0.dp).weight(1f),
            )
        }
        Row {
            checkBox(
                text = "四字", checked = filter.l4,
                onCheckedChange = { p.updateFilter { copy(l4 = it) } },
                modifier = Modifier.width(0.dp).weight(1f)
            )

            checkBox(
                text = "多字", checked = filter.l9,
                onCheckedChange = { p.updateFilter { copy(l9 = it) } },
                modifier = Modifier.width(0.dp).weight(1f)
            )
            Spacer(modifier = Modifier.width(0.dp).weight(1f))
        }

    }
}

@Composable
private fun EditorView.wordFreqFilter(modifier: Modifier) {
    if (p.model.data.wordFrequency == null) return
    val filter by p.filterState
    groupRow("词频筛选", modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
        imageVectorButton(
            tooltip = "最小",
            icon = Icons.Default.ArrowBack,
            modifier = Modifier.mini().width(10.dp),
            onClick = {
                p.updateFilter {
                    copy(minWF = p.model.data.wordFrequency?.min() ?: 0)
                }
            }
        )
        BasicTextField(
            value = filter.minWF.toString(),
            onValueChange = {
                it.ifBlank { "0" }.toIntOrNull()?.also { i ->
                    p.updateFilter { copy(minWF = i) }
                }
            },
            singleLine = true,
            modifier = Modifier.width(0.dp).weight(1f).wrapContentSize(Alignment.Center).padding(start = 3.dp),
        )
        Text("<=>", modifier = Modifier.padding(horizontal = 3.dp))
        BasicTextField(
            value = filter.maxWF.toString(),
            onValueChange = {
                it.ifBlank { "0" }.toIntOrNull()?.also { i ->
                    p.updateFilter { copy(maxWF = i) }
                }
            },
            singleLine = true,
            modifier = Modifier.width(0.dp).weight(1f).wrapContentSize(Alignment.Center).padding(end = 3.dp),
        )
        imageVectorButton(
            tooltip = "最大",
            icon = Icons.Default.ArrowForward,
            modifier = Modifier.mini().width(20.dp),
            onClick = {
                p.updateFilter {
                    copy(maxWF = p.model.data.wordFrequency?.max() ?: Int.MAX_VALUE)
                }
            }
        )
    }
}

@Composable
private fun checkBox(
    text: String,
    checked: Boolean,
    onCheckedChange: ((Boolean) -> Unit),
    modifier: Modifier = Modifier,
) {
    Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
        Checkbox(checked = checked, onCheckedChange = onCheckedChange)
        Text(
            text = text,
            modifier = Modifier.clickable { onCheckedChange(!checked) }
        )
    }
}

@Composable
private fun EditorView.contentAreal(modifier: Modifier) {
    val scrollbarStyle = ScrollbarStyle(
        minimalHeight = 100.dp,
        thickness = 15.dp,
        shape = RoundedCornerShape(3.dp),
        hoverDurationMillis = 300,
        unhoverColor = Color.Black.copy(alpha = 0.12f),
        hoverColor = Color.Black.copy(alpha = 0.40f)
    )
    val state: LazyListState = rememberLazyListState()

    Box(modifier = modifier) {
        var lines: Int by remember { mutableStateOf(0) }
        val bottomHeight = ButtonDefaults.MinHeight
        Box(
            modifier = Modifier.padding(3.dp).padding(bottom = bottomHeight)
        ) {
            LazyColumn(modifier = Modifier.fillMaxSize(), state = state) {
                itemsIndexed(
                    p.model.data.table.values.toList().filter(p.itemFilterPredicate).sortedBy { it.code }
                        .also { lines = it.size }
                ) { index, item ->
                    CodeItemComp(
                        rowNumber = index + 1,
                        codeItem = item,
                        wordFrequency = p.model.data.wordFrequency,
                    )
                }
            }
        }
        addItemButton(Modifier.height(bottomHeight).align(Alignment.BottomStart))
        tableInfo(lines, modifier = Modifier.align(Alignment.BottomEnd).padding(end = 20.dp))
        VerticalScrollbar(
            adapter = ScrollbarAdapter(state),
            modifier = Modifier.align(Alignment.CenterEnd),
            style = scrollbarStyle
        )
    }
}

@Composable
private fun EditorView.addItemButton(modifier: Modifier) {
    var codeValue by remember { mutableStateOf("") }
    var wordValue by remember { mutableStateOf("") }

    Row(modifier, verticalAlignment = Alignment.CenterVertically) {
        Text(text = "编码", modifier = Modifier.padding(end = 5.dp))
        BasicTextField(
            value = codeValue,
            onValueChange = { codeValue = it },
            modifier = Modifier.width(100.dp).border(1.dp, Color.LightGray).height(24.dp).padding(horizontal = 1.dp)
                .wrapContentSize(Alignment.CenterStart),
            singleLine = true,
            textStyle = MaterialTheme.typography.body1.copy(fontSize = 15.sp),
        )
        Spacer(Modifier.size(10.dp))
        Text(text = "词条", modifier = Modifier.padding(end = 5.dp))
        BasicTextField(
            value = wordValue,
            onValueChange = { wordValue = it },
            modifier = Modifier.width(100.dp).border(1.dp, Color.LightGray).height(24.dp).padding(horizontal = 1.dp)
                .wrapContentSize(Alignment.CenterStart),
            singleLine = true,
            textStyle = MaterialTheme.typography.body1.copy(fontSize = 15.sp),
        )
        Spacer(Modifier.size(10.dp))
        Button(
            onClick = {
                if (codeValue.isBlank() || wordValue.isBlank()) return@Button
                p.addAndUpdate(codeValue.toCode(), wordValue.toWord())
                p.save()
                codeValue = ""
                wordValue = ""
            }
        ) {
            Text("添加词条")
        }
    }
}

@Composable
fun EditorView.tableInfo(lines: Int, modifier: Modifier) {
    val table = p.model.data.table
    Column(modifier = modifier, horizontalAlignment = Alignment.Start) {
        Text(text = "总编码数：${table.size}", color = Color.LightGray)
        Text(text = "总词条数：${table.wordSize()}", color = Color.LightGray)
        Text(text = "当前行数：$lines", color = Color.LightGray)
    }
}